#include "serial.h"

/* 设置串口 setup_serial(fd,115200,8,'N',1) */
int setup_serial(int fd, int nSpeed, int nBits, char nEvent, int nStop) {
	struct termios options;

	memset(&options, 0, sizeof(options));
	/* 获取当前串口配置 */
	if (tcgetattr(fd, &options) != 0) {
		fprintf(stderr, "Error from tcgetattr: %s\n", strerror(errno));
		return -1;
	}

	/* 配置波特率 */
	switch (nSpeed)
	{
	case 2400:
		cfsetispeed(&options, B2400);
		cfsetospeed(&options, B2400);
		break;
	case 4800:
		cfsetispeed(&options, B4800);
		cfsetospeed(&options, B4800);
		break;
	case 9600:
		cfsetispeed(&options, B9600);
		cfsetospeed(&options, B9600);
		break;
	case 115200:
		cfsetispeed(&options, B115200);
		cfsetospeed(&options, B115200);
		break;
	default:
		cfsetispeed(&options, B9600);
		cfsetospeed(&options, B9600);
		break;
	}
	/* 配置控制模式：无校验位，8个数据位，1个停止位 */
	options.c_cflag |= CLOCAL | CREAD;	// ignore modem controls
	options.c_cflag &= ~CSIZE;	// 清除数据位数设置

	switch (nBits)
	{
	case 7:
		options.c_cflag |= CS7;
		break;
	case 8:
		options.c_cflag |= CS8;	 // 设置8个数据位
		break;
	}

	switch (nEvent)
	{
	case 'O':
		options.c_cflag |= PARENB;
		options.c_cflag |= PARODD;
		options.c_iflag |= (INPCK | ISTRIP);
		break;
	case 'E':
		options.c_iflag |= (INPCK | ISTRIP);
		options.c_cflag |= PARENB;
		options.c_cflag &= ~PARODD;
		break;
	case 'N':
		options.c_cflag &= ~PARENB;	// 关闭奇偶校验位
		break;
	}

	if (nStop == 1)
		options.c_cflag &= ~CSTOPB;		// 设置1个停止位
	else if (nStop == 2)
		options.c_cflag |= CSTOPB;
	

	/* 设置本地模式：无硬件流控 */
	options.c_cflag &= ~CRTSCTS;

	/* 设置原始输入模式：无处理，无回显 */
	options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

	/* 设置输出模式：无处理 */
	options.c_oflag &= ~OPOST;

	/* 设置等待时间和最小接收字符 */
	options.c_cc[VTIME] = 100;   // 设置从获取到1个字节后开始计时的超时时间
	options.c_cc[VMIN] = 0;    // 设置要求等待的最小字节数

	/* 应用配置 */
	tcflush(fd, TCIFLUSH);
	if ((tcsetattr(fd, TCSANOW, &options)) != 0)
	{
		perror("com set error");
		return -1;
	}
	return 0;
}

/* 打开串口 */
int open_port(char* com)
{
	int fd;
	//fd = open(com, O_RDWR|O_NOCTTY|O_NDELAY);
	fd = open(com, O_RDWR | O_NOCTTY | O_SYNC);		// O_RDWR | O_NOCTTY
	if (-1 == fd) {
		printf("open serial is failed!\n");
		return -1;
	}

	if (fcntl(fd, F_SETFL, 0) < 0)	// 恢复串口为阻塞状态
	{
		printf("fcntl failed!\n");
		return -1;
	}
	return fd;
}

/* 接收串口数据 */
int serial_recv(int fd, uint8_t* rev_buf, int data_len) {
	int ret;
	int count = 0;
	while (data_len > 0)
	{
		ret = read(fd, rev_buf + count, data_len);  // fd所指的文件传送data_len个字节到rcv_buf中
		count += ret;
		data_len = data_len - ret;
	}
	return count;
}

/* 解析串口数据 */
int analysis_data(ssize_t bytes_read, uint8_t* rev_buf, NMEA* nmea) {
	
	for (int i = 0; i < bytes_read;) {
		if (rev_buf[i++] == 0x24) {
			if (rev_buf[i] == gn_value[0] && rev_buf[i+1] == gn_value[1]) {
				i = i + 2;
				if (rev_buf[i] == gga_value[0] && rev_buf[i + 1] == gga_value[1] && rev_buf[i + 2] == gga_value[2]) {
					i = i + 3;

					if (rev_buf[i++] == 0x2C) {
						if(rev_buf[i] != 0x2C)
					}
					if(rev_buf[i++] == 0x0D && rev_buf[i++] == 0x0A)

				}
				else if (rev_buf[i] == gll_value[0] && rev_buf[i + 1] == gll_value[1] && rev_buf[i + 2] == gll_value[2]) {
					i = i + 3;
				}
				else if (rev_buf[i] == gsa_value[0] && rev_buf[i + 1] == gsa_value[1] && rev_buf[i + 2] == gsa_value[2]) {
					i = i + 3;
				}
				else if (rev_buf[i] == rmc_value[0] && rev_buf[i + 1] == rmc_value[1] && rev_buf[i + 2] == rmc_value[2]) {
					i = i + 3;
				}
				else if (rev_buf[i] == vtg_value[0] && rev_buf[i + 1] == vtg_value[1] && rev_buf[i + 2] == vtg_value[2]) {
					i = i + 3;
				}
				else if (rev_buf[i] == zda_value[0] && rev_buf[i + 1] == zda_value[1] && rev_buf[i + 2] == zda_value[2]) {
					i = i + 3;
				}
			}
			else if (rev_buf[i] == gl_value[0] && rev_buf[i+1] == gl_value[1]) {
				i = i + 2;
				if (rev_buf[i] == gsv_value[0] && rev_buf[i + 1] == gsv_value[1] && rev_buf[i + 2] == gsv_value[2]) {
					i = i + 3;
				}

			}
			else if (rev_buf[i] == gp_value[0] && rev_buf[i+1] == gp_value[1]) {
				i = i + 2;
				if (rev_buf[i] == gsv_value[0] && rev_buf[i + 1] == gsv_value[1] && rev_buf[i + 2] == gsv_value[2]) {
					i = i + 3;
				}
				else if (rev_buf[i] == txt_value[0] && rev_buf[i + 1] == txt_value[1] && rev_buf[i + 2] == txt_value[2]) {
					i = i + 3;
				}
			}
		}
	}
	return 0;
}


unsigned int hexdigit(char c) {
	if (isdigit(c)) {
		return c - '0';
	}
	else if (isupper(c)) {
		return 10 + (c - 'A');
	}
	else if (islower(c)) {
		return 10 + (c - 'a');
	}
	else {
		fprintf(stderr, "Invalid hexadecimal digit: %c\n", c);
		exit(EXIT_FAILURE);
	}
	return 0; // 不应该到达这里
}

/* 16进制整数，转换成ASCII码字符
param:
	unsigned char hex = 0x41;
return:
	char asciiChar = hexToAscii(hex);	// asciiChar = 'A'
*/
char hexToAscii(unsigned char hex) {
	// 直接将16进制值作为ASCII码返回
	return hex;
}

/* 16进制整数，转换成ASCII码整数
param:
	unsigned char hex = 0x41;
return:
	int asciiChar = hexToAscii(hex);	// asciiChar = 65 对应10进制表示形式
*/
int hexToAscii(unsigned char hex) {
	// 直接将16进制值作为ASCII码返回
	return hex;
}

/* 字符串形式的16进制，转换为ASCII码字符
param:
	const char *hexValue = "41"; 
return:
	char asciiChar = hexStringToAscii(hexValue);	// asciiChar = 'A'
*/
char hexStringToAscii(const char* hex) {
	unsigned char value;

	if (strlen(hex) != 2) {
		fprintf(stderr, "Invalid hexadecimal string. It must be 2 characters long.\n");
		exit(EXIT_FAILURE);
	}

	// 将两个字符转换为数字
	value = (hexdigit(hex[0]) << 4) + hexdigit(hex[1]);

	// 返回对应的 ASCII 字符
	return value;
}

/*字符转为整数
param:
	char digitChar = '7';
return:
	int digit = charToDigit(digitChar);		// digit=7
*/
int charToDigit(char c) {
	if (c >= '0' && c <= '9') {
		return c - '0';
	}
	else {
		fprintf(stderr, "Invalid digit character: %c\n", c);
		exit(EXIT_FAILURE);
	}
}

/*ASCII码转为16进制字符
param:
	char ascii = 'A'; // ASCII字符
    char hex[3]; // 用于存储16进制字符串，最多需要2位加上空字符
return:
	None	// printf("%s",hex)->41	 printf("0x%s",hex)->0x41
*/
void asciiToHex(char ascii, char* hex) {
	sprintf(hex, "%02X", ascii);	// 将ASCII字符转换为16进制字符串，并格式化为两位
}



